﻿using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using BoldBrick.Core.Logging;
using BoldBrick.OneIntranet.HR.Properties;
using BoldBrick.OneIntranet.HR.Resources;
using BoldBrick.SharePoint.CommonControls.DataObjects.Query;
using BoldBrick.SharePoint.CommonControls.Utils;
using BoldBrick.Web.Parameters;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using BoldBrick.SharePoint.CommonControls.Extensions;
using System.Linq;

namespace BoldBrick.OneIntranet.HR.FieldTypes
{
	public class ContentTypeLookupControl : BaseFieldControl
	{
		private static readonly ILogger log = Logger.GetLogger(typeof(ContentTypeLookupControl));

		#region ------ Value ----------------------------------------------------------------------

		public override object Value
		{
			get
			{
				EnsureChildControls();
				
				if (this.dropDownList.SelectedItem == null || (!this.Field.Required && this.dropDownList.SelectedIndex == 0))
					return null;

				ContentTypeLookupValue value = new ContentTypeLookupValue(this.dropDownList.SelectedItem.Value, this.dropDownList.SelectedItem.Text);
				return value;
			}
			set
			{
				EnsureChildControls();
				if (value != null)
				{
					ContentTypeLookupValue contentTypeLookupValue = new ContentTypeLookupValue(value.ToString());
					this.dropDownList.SelectedValue = contentTypeLookupValue.ContentTypeId;
				}
			}
		}

		#endregion

		#region ------ Controls -------------------------------------------------------------------

		protected HtmlGenericControl divError;
		protected DropDownList dropDownList;

		protected override void CreateChildControls()
		{
			base.CreateChildControls();

			uint language = SPContext.Current.Web.Language;

			// create error div
			divError = new HtmlGenericControl("div")
			           	{
			           		ID = "divError"
			           	};
			divError.Style[HtmlTextWriterStyle.Color] = "red";
			divError.Style[HtmlTextWriterStyle.Display] = "none";
			this.Controls.Add(divError);

			// check base content type id
			string baseContentTypeId = this.Field.GetCustomProperty<string>(Settings.Default.Field_ContentTypeLookup_CustomProperty_BaseContentTypeId_Name, null);
			if (string.IsNullOrEmpty(baseContentTypeId))
			{
				string message = ResourceBuilder.GetResource("ContentTypeLookupControl_Error_BaseContentTypeIdIsNotSet", language);
				ShowError(message);
				return;
			}
			// create main div
			HtmlGenericControl divMain = new HtmlGenericControl("div")
			                             	{
			                             		ID = "divMain"
			                             	};
			this.Controls.Add(divMain);

			// create drop down
			dropDownList = new DropDownList
			               	{
			               		ID = "dropDownListContentTypes"
			               	};
			divMain.Controls.Add(dropDownList);

			CreateListItems(baseContentTypeId);
		}

		private void CreateListItems(string baseContentTypeId)
		{
			uint language = SPContext.Current.Web.Language;

			if (this.dropDownList.Items.Count > 0)
				return;
			
			bool isRequired = this.Field.Required;
			
			// add (none) item if field is not required
			if (!isRequired)
			{
				string itemNone = ResourceBuilder.GetResource("ContentTypeLookupControl_ItemNone_Title", language);
				this.dropDownList.Items.Add(new ListItem(itemNone, null));
			}

			// create content type ID
			SPContentTypeId baseSpContentTypeId;
			try
			{
				baseSpContentTypeId = new SPContentTypeId(baseContentTypeId);
			}
			catch (Exception ex)
			{
				string message = ResourceBuilder.GetResource("ContentTypeLookupControl_Error_BaseContentTypeIdIsBad", language);
				ShowError(message);
				log.Write(LogLevel.Error, ex, "Creating of ContentTypeId object failed.");
				return;
			}

			// convert child content types to list items
			ListItem[] listItems = SPContext.Current.Web.ContentTypes.OfType<SPContentType>()
				.Where(contentType => contentType.Id.IsChildOf(baseSpContentTypeId) && !contentType.Id.Equals(baseSpContentTypeId))
				.Select(contentType => new ListItem(contentType.Name, contentType.Id.ToString()))
				.OrderBy(item => item.Text)
				.ToArray();

			this.dropDownList.Items.AddRange(listItems);
		}

		#endregion

		#region ------ Display --------------------------------------------------------------------

		protected override void RenderFieldForDisplay(HtmlTextWriter output)
		{
			if (this.ItemFieldValue == null)
				return;

			ContentTypeLookupValue value = new ContentTypeLookupValue(this.ItemFieldValue.ToString());

			string url = SPContext.Current.Web.ServerRelativeUrl;
			url = UrlHelper.CombineURLPath(url, "/_layouts/ManageContentType.aspx");

			ContentTypePageQueryParameters query = new ContentTypePageQueryParameters
			                                       	{
			                                       		ContentType = value.ContentTypeId
			                                       	};
			RequestQueryParametersProvider provider = new RequestQueryParametersProvider();
			string queryString = provider.BuildQuery(query);
			url = string.Format("{0}?{1}", url, queryString);

			string anchor = string.Format("<a href=\"{0}\">{1}</a>", url, value.ContentTypeName);
			output.Write(anchor);
		}

		#endregion

		#region ------ Validation -----------------------------------------------------------------

		public override void Validate()
		{
			base.Validate();

			if (!this.Field.Required)
				return;

			if (this.Value == null)
				this.IsValid = false;
		}

		#endregion

		#region ------ Errors ---------------------------------------------------------------------

		private void ShowError(string message)
		{
			EnsureChildControls();
			
			divError.Style[HtmlTextWriterStyle.Display] = "block";
			divError.InnerText = message;
		}

		#endregion
	}
}
